package utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 对象子类
 *
 * @author Administrator
 */
public class BaseObject implements Serializable {

    public BaseObject() {
    }

    public List<? extends BaseObject> fromJsonArray(String jsons) {
        List<BaseObject> es = new ArrayList<BaseObject>();
        jsons = jsons.trim();
        if (jsons.startsWith("{")) {
            jsons = "[" + jsons + "]";
        }
        JSONArray jsonArray = JSONArray.parseArray(jsons);
        for (int i = 0; i < jsonArray.size(); i++) {
            BaseObject e = BaseObject.formJson(jsonArray.get(i).toString(), this.getClass());
            es.add(e);
        }
        return es;
    }

    public JSONObject toJsonObject() {
        String result = JSONObject.toJSONString(this, SerializerFeature.DisableCircularReferenceDetect);
        return JSONObject.parseObject(result);
    }

    @Override
    public String toString() {
        return JSONObject.toJSONString(this);
    }

    public Map<String, Object> toMap() {
        Map<String, Object> map = json2Map(this.toString());
        return map;
    }

    /**
     * 将当前对象转换成另一个对象
     *
     * @param cls
     * @param <T>
     * @return
     */
    public <T> T toObject(Class<T> cls) {
        return BaseObject.formJson(this.toString(), cls);
    }

    /**
     * 将当前对象转换成xml格式
     *
     * @param parentName
     * @return
     */
    public String parseXml(String parentName) {
        return parseXml(parentName, this);
    }

    public static String toString(Object object) {
        return JSONObject.toJSONString(object);
    }

    public static <T> T formJson(String json, Class<T> clazz) {
        return JSONObject.parseObject(json, clazz);
    }

    public static Map<String, Object> json2Map(String json) {
        return JSON.parseObject(json, Map.class);
    }

    public static <T> T toObject(Serializable object, Class<T> cls) {
        return BaseObject.formJson(JSONObject.toJSONString(object), cls);
    }

    public static JSONObject mapToJson(Map<String, Object> map) {
        String jsonStr = JSON.toJSONString(map);
        return JSON.parseObject(jsonStr);
    }

    public static <T> T mapToObject(Map<String, Object> map, Class<T> cls) {
        String jsonStr = JSON.toJSONString(map);
        return JSONObject.parseObject(jsonStr, cls);
    }

    /**
     * BaseObject对象转xml
     *
     * @param parentName
     * @param object
     * @return
     */
    public static String parseXml(String parentName, BaseObject object) {
        JSONObject jsonObject = object.toJsonObject();
        return parseXml(parentName, jsonObject);
    }

    /**
     * jsonObject转换为xml
     *
     * @param parentName
     * @param jsonObject
     * @return
     */
    private static String parseXml(String parentName, JSONObject jsonObject) {
        StringBuilder sb = new StringBuilder("<" + parentName + ">");
        Set<String> keys = jsonObject.keySet();
        Object value;
        for (String key : keys) {
            value = jsonObject.get(key);
            if (value instanceof JSONObject) {
                sb.append(parseXml(key, (JSONObject) value));
            } else if (value instanceof JSONArray) {
                sb.append(parseXml(key, (JSONArray) value));
            } else {
                sb.append("<" + key + ">" + value + "</" + key + ">");
            }
        }
        sb.append("</" + parentName + ">");
        return sb.toString();
    }


    /**
     * JsonArray转换为xml
     *
     * @param parentName
     * @param jsonArray
     * @return
     */
    private static String parseXml(String parentName, JSONArray jsonArray) {
        StringBuilder sb = new StringBuilder();
        int size = jsonArray.size();
        Object value;
        for (int i = 0; i < size; i++) {
            value = jsonArray.get(i);
            if (value instanceof JSONObject) {
                sb.append(parseXml(parentName, (JSONObject) value));
            } else if (value instanceof JSONArray) {
                sb.append(parseXml(parentName, (JSONArray) value));
            } else {
                sb.append("<" + parentName + ">" + value + "</" + parentName + ">");
            }
        }
        return sb.toString();
    }
}
